﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Windows.Forms;
using Castle.MicroKernel.Handlers;


namespace CHPM.PL.DesktopUI.Code.Validation
{
    public class NewPatientValidator
    {
        private ErrorProvider _errorProvider;

        public NewPatientValidator(ErrorProvider errorProvider)
        {
            _errorProvider = errorProvider;
        }

        #region Constants

        private const string _requiredField = "Обов’язкове поле!";

        #region Full Name fields

        private const int _fullNameMaxLength = 100;
        private const int _fullNameMinLength = 6;
        private const string _fullNameMaxLengthMessage = "Перевищено максимальну довжину імені пацієнта! (100 символів)";
        private const string _fullNameMinLengthMessage = "Недопустимо коротке ім’я!";

        #endregion

        #region Adress Fields

        private const int _adressMaxLength = 255;
        private const int _adressMinLength = 1;
        private const string _adressMaxLengthMessage = "Перевищено максимальну довжину адреси пацієнта! (255 символів)";
        private const string _adressMinLengthMessage = "Недопустимо коротка адреса!";

        #endregion

        #region Phone Fields

        private const string _phoneWrongValue = "Введене значення не відповідає формату: 077-777-7777";

        #endregion 
        #region CardNumber Fields

        private const string _cardNumberWrongValue = "У введеному значенні мають бути лише цифри";
        private const int _cardNumberMaxLength = 6;

        #endregion 

        #region Phone Fields



        #endregion

        #endregion

        public  List<string> FullNameValidation(string name)
        {
            List<string> messages = new List<string>();
            if (MaxLengthCheck(name, _fullNameMaxLength))
            {
                messages.Add(_fullNameMaxLengthMessage);
            }
            if (MinLengthCheck(name, _fullNameMinLength))
            {
                messages.Add(_fullNameMinLengthMessage);
            }
            return messages;
        }

        public  void FullNameValidation(Object sender, CancelEventArgs e)
        {
            List<string> messages = new List<string>();
            Control tFullName = sender as Control;
            string error = null;
            if (tFullName != null)
            {
                string name = tFullName.Text;

                if (name == String.Empty)
                {
                    error = _requiredField;
                    e.Cancel = true;
                }
                else
                {
                    if (MaxLengthCheck(name, _fullNameMaxLength))
                    {
                        messages.Add(_fullNameMaxLengthMessage);
                        e.Cancel = true;
                    }
                    if (MinLengthCheck(name, _fullNameMinLength))
                    {
                        messages.Add(_fullNameMinLengthMessage);
                        e.Cancel = true;
                    }
                    error = ErrorStringBuilder(messages);
                }
                _errorProvider.SetError(tFullName,error);
            }
            else
            {
                throw new HandlerException("No such control (FullNameValidation)");
            }
        }

        public void AdressValidation(Object sender, CancelEventArgs e)
        {
            List<string> messages = new List<string>();
            Control tAdress = sender as Control;

            string error = null;
            if (tAdress != null)
            {
                string adress = tAdress.Text;

                if (adress == String.Empty)
                {
                    error = _requiredField;
                    e.Cancel = true;
                }
                else
                {

                    if (MaxLengthCheck(adress, _adressMaxLength))
                    {
                        messages.Add(_adressMaxLengthMessage);
                        e.Cancel = true;
                    }
                    if (MinLengthCheck(adress, _adressMinLength))
                    {
                        e.Cancel = true;
                        messages.Add(_adressMinLengthMessage);
                    }
                
                    error = ErrorStringBuilder(messages);
                }
                _errorProvider.SetError(tAdress, error);
            }
            else
            {
                throw new HandlerException("No such control (AdressValidation)");
            }
        }

        public void PhoneValidation(Object sender, CancelEventArgs e)
        {
            Control tPhone = sender as Control;

            string error = null;
            if (tPhone != null)
            {
                string phone = tPhone.Text;

                if (phone == String.Empty)
                {
                    error = _requiredField;
                    e.Cancel = true;
                }
               if (!phoneCheck(phone))
                {
                    error = _phoneWrongValue;
                    e.Cancel = true;
                }
                _errorProvider.SetError(tPhone, error);
            }
            else
            {
                throw new HandlerException("No such control (PhoneValidation)");
            }
        }

        public void CardNumberValidation(Object sender, CancelEventArgs e)
        {
             Control tCardNumber = sender as Control;

            string error = null;
            if (tCardNumber != null)
            {
                string cardNumber = tCardNumber.Text;

                if (cardNumber == String.Empty)
                {
                    error = _requiredField;
                    e.Cancel = true;
                }
                if (!cardNumberCheck(cardNumber))
                {
                    error = _cardNumberWrongValue;
                    e.Cancel = true;
                }
                _errorProvider.SetError(tCardNumber, error);
            }
            else
            {
                throw new HandlerException("No such control (PhoneValidation)");
            }
        }

        public  List<string> AdressValidation(string adress)
        {
            List<string> messages = new List<string>();

            if (MaxLengthCheck(adress, _adressMaxLength))
            {
                messages.Add(_adressMaxLengthMessage);
            }
            if (MinLengthCheck(adress, _adressMinLength))
            {
                messages.Add(_adressMinLengthMessage);
            }
            return messages;
        }

        #region Helpers

        private  bool MaxLengthCheck(string str, int maxLength)
        {
            return str.Length > maxLength;
        }

        private  bool MinLengthCheck(string str, int minLength)
        {
            return str.Length < minLength;
        }

        private  bool phoneCheck(string phoneStr)
        {
            Regex TheRegExpression;
            string TheRegExTest = @"0\d{2}-\d{3}-\d{4}";
            TheRegExpression = new Regex(TheRegExTest);
            if (TheRegExpression.IsMatch(phoneStr))
            {
                return true;
            }
            return false;
        }

        private bool cardNumberCheck(string cardNumber)
        {
            Regex TheRegExpression;
            string TheRegExTest = String.Format(@"\d{0}", _cardNumberMaxLength);
            TheRegExpression = new Regex(TheRegExTest);
            if (TheRegExpression.IsMatch(cardNumber))
            {
                return true;
            }
            return false;
        }

        private  string ErrorStringBuilder(List<string> errors)
        {
            if(errors.Count > 0)
            {
                string error = String.Empty;
                foreach (string s in errors)
                {
                    var tmp = String.Format("- {0};/n", s);
                    if (error != String.Empty)
                    {
                        if (s.Equals(errors[errors.Count - 1]))
                        {
                            error += String.Format("- {0}./n", s);
                        }
                        else
                        {
                             error += tmp;
                        }
                    }
                    else 
                    {
                        if(s.Equals(errors[0]))
                        {
                            error = tmp;
                        }
                    }
                }
                return error;
            }
            return null;
        }

        #endregion
    }
}
